<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Presentation Levels Module</title>
<link href="../default.css" rel="stylesheet" type="text/css" title="Default" />
<style type="text/css" title="Default">
/* The TR postprocessor, unlike Bikeshed, already inserted quotes: */
.css::before, .property::before, .descriptor::before {content: none}
.css::after, .property::after, .descriptor::after {content: none}
</style>
<link rel="stylesheet"
href="https://www.w3.org/StyleSheets/TR/W3C-MO.css"
type="text/css" title="Default" />
</head>
<body>
<div class="head">
<p><a href="http://www.w3.org/"><img alt="W3C" height="48"
src="https://www.w3.org/Icons/w3c_home" width="72" /></a></p>

<h1 id="title">CSS Presentation Levels Module</h1>

<h2 id="W3C-doctype" class="no-num no-toc">[LONGSTATUS] [DATE]</h2>

<dl>
<dt>This version:</dt>

<dd><a
href="https://www.w3.org/TR/[YEAR]/[STATUS]-css3-preslev-[CDATE]/">[VERSION]</a></dd>

<dt>Latest version:</dt>

<dd><a
href="https://www.w3.org/TR/css3-preslev">https://www.w3.org/TR/css3-preslev</a></dd>

<dt>Previous version:</dt>

<dd><a href="https://www.w3.org/TR/2014/NOTE-css3-preslev-20141014/"
>https://www.w3.org/TR/2014/NOTE-css3-preslev-20141014/</a></dd>

<dt>Feedback:
<dd><a href="mailto:www-style@w3.org?subject=%5Bcss-preslev%5D%20feedback">www-style@w3.org</a>
    with subject line &ldquo;<kbd>[css-preslev] <var>&hellip; message topic &hellip;</var></kbd>&rdquo;
    (<a rel="discussion" href="http://lists.w3.org/Archives/Public/www-style/">archives</a>)


<dt>Editors:</dt>

<dd><a lang="en" href="http://ian.hixie.ch/">Ian Hickson</a>
&lt;ian&nbsp;@hixie.ch&gt;</dd>

<dd><a lang="no" href="http://people.opera.com/howcome/">Håkon Wium
Lie</a> &lt;howcome&nbsp;@opera.com&gt;</dd>

<dd><a lang=nl href="http://www.w3.org/People/Bos/">Bert Bos</a> (W3C)
&lt;bert&nbsp;@w3.org&gt;</dd>

</dl>

<!--begin-copyright-->
<p>[Here will be included the file "../copyright.inc"]</p>
<!--end-copyright-->

<hr title="Separator for header" />
</div>



<h2 class="no-num no-toc" id="abstract">Abstract</h2>

<p>Presentation levels are integer values attached to elements in a
document. Elements that are below, at, or above a certain threshold
can be styled differently. This feature has two compelling use
cases. First, slide presentations with transition effects can be
described. For example, list items can be progressively revealed by
sliding in from the side. Second, outline views of documents, where
only the headings to a certain level are visible, can be
generated.</p>

<h2 class="no-num no-toc" id="status">Status of This Document</h2>

<!--status-->

<p class=mtb><em>At this time, the CSS Working Group does not envisage
further work on this specification and does not plan to propose it as
a W3C Recommendation.</em>



<nav id="toc">
<h2 class="no-num no-toc" id="contents">Table of contents</h2>
<!--toc-->
</nav>

<h2 id="themodel">The model</h2>

<p>Content reuse has been one of the main motivations for the
development of style sheets. By associating documents with
different style sheets, the same content can be presented in
different ways. The introduction of <em>presentation levels</em> in
CSS adds functionality which is very useful in two particular
settings. First, slide presentations with transition effects can be
described. For example, list items can be progressively revealed by
sliding in from the side. Second, outline views of documents, where
only the headings to a certain level are visible, can be
generated.</p>

<p>The model behind presentation levels is simple. Each element in
the document is assigned an integer value which is referred to as
the "element's presentation level" (EPL). The EPL can be set
explicitly in a style sheet or calculated automatically based on
the element's position in the document structure: it is specified
by the computed value of the <span
class="property">'presentation-level'</span> property. The
User Agent maintains another integer value which is called the User
Agent Presentation Value (UAPL). The UAPL starts at a UA-defined
value, typically 0.</p>

<p>All elements are in one of three presentation pseudo-classes:
<span class="css">'below-level'</span>, <span
class="css">'at-level'</span>, and <span
class="css">'above-level'</span>. These pseudo-classes
refer to whether the element's EPL was below, at, or above the UAPL
the last time the UAPL changed. When an element's state is
evaluated, the EPL is compared to the UAPL and pseudo-classes are
assigned as follows: If the EPL is equal to 0, the element is
always in the below-level state. If the EPL is lower than the UAPL
value, it is set to the 'below-level' state, if the EPL is exactly
that value it is set to 'at-level', and if the EPL is greater than
that value it is set to 'above-level'.</p>

<p>Here is an example of a style sheets using the presentation
pseudo-classes:</p>

<pre>
  :below-level { color: black }
  :at-level { color: red }
  :above-level { color: silver }
</pre>

<p>This proposal does not describe the user interface of
presentation levels. The user agent will need to provide a user
interface for setting the UAPL. For example, in projection mode, a
user agent may increase the UAPL every time the user hits the space
bar. When the user moves to another page (for example by following
a hyperlink), the user agent may set the UAPL to be the same as
presentation level of the first element on the page. In outline
mode, the user agent may provide a vertical slider on the side to
increase/decrease the UAPL.</p>

<h2 id="presentation-level-property">The 'presentation-level' property</h2>

<table class="propdef">
<tr>
<td><em>Name:</em></td>
<td><dfn id="presentation-level">presentation-level</dfn></td>
</tr>

<tr>
<td><em>Value:</em></td>
<td>&lt;integer&gt; | same | increment</td>
</tr>

<tr>
<td><em>Initial:</em></td>
<td>0</td>
</tr>

<tr>
<td><em>Applies to:</em></td>
<td>all elements</td>
</tr>

<tr>
<td><em>Inherited:</em></td>
<td>yes</td>
</tr>

<tr>
<td><em>Percentages:</em></td>
<td>N/A</td>
</tr>

<tr>
<td><em>Computed&nbsp;value:</em></td>
<td>integer</td>
</tr>
</table>

<p class=all-media>User Agents are expected to support this property on all media, including non-visual ones.</p>

<p>This property sets the element's presentation level (EPL). The
values have the following meanings:</p>

<ul>
<li>An integer value sets the presentation level explicitly.</li>

<li>A value of <span class="css">'increment'</span> computes to a
value one more than the
previous (in document order) element's presentation level.</li>

<li>A value of <span class="css">'same'</span> computes to the same
value as the previous
element's (in document order) presentation level. For the root
element, <span class="css">'same'</span> computes to zero.</li>
</ul>

<h2 id="example1">Example 1: progressively revealing list items</h2>

<p>Here is an example of how presentation levels can be used to
progressively reveal list items while high-lighting the current
one.</p>

<pre>
                                                   EPL value
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"&gt;
&lt;HTML&gt;                                             0
&lt;STYLE&gt;                                            0
  html { color: black; background: white }
  @media projection {
    h1 { page-break-before: always }
    li { presentation-level: increment }
    :below-level { color: black }
    :at-level { color: red }
    :above-level { color: silver }
  }
&lt;/STYLE&gt;
&lt;BODY&gt;                                             0
&lt;H1&gt;Strategies&lt;/H1&gt;                                0
&lt;H2&gt;Our strategy&lt;/H2&gt;                              0
&lt;UL&gt;                                               0
  &lt;LI&gt;divide                                       1
  &lt;LI&gt;conquer                                      2
  &lt;P&gt;(in that order)                               2
&lt;/UL&gt;
&lt;H2&gt;Their strategy&lt;/H2&gt;                            0
&lt;UL&gt;                                               0
  &lt;LI&gt;obfuscate                                    1
  &lt;LI&gt;propagate                                    2
&lt;/UL&gt;
</pre>

<p>In the example above, the LI elements' EPL value is increased
with one compared to the previous element. The other elements' EPL
value is the same as the previous element due to the initial <span
class="css">'same'</span>
value of the <span class="property">'presentation-level'</span>
property.</p>

<h2 id="example2">Example 2: presenting outline views of a document</h2>

<p>Here is an example of how presentation levels can be used to
present outline views of a document:</p>

<pre>
                                                   EPL value
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"&gt;
&lt;HTML&gt;                                             0
&lt;STYLE&gt;   
   h1 { presentation-level: 0; }
   h2 { presentation-level: 1; }
   h3 { presentation-level: 2; }
   body * { presentation-level: 3; }
   :above-level { display: none; }
&lt;/STYLE&gt;
&lt;BODY&gt;                                             0
&lt;H1&gt;Strategies&lt;/H1&gt;                                3
&lt;H2&gt;Our strategy&lt;/H2&gt;                              2
&lt;UL&gt;                                               0
&lt;LI&gt;divide                                         0
&lt;LI&gt;conquer                                        0
&lt;P&gt;(in that order)                                 0
&lt;/UL&gt;
&lt;H2&gt;Their strategy&lt;/H2&gt;                            2
&lt;UL&gt;                                               0
&lt;LI&gt;obfuscate                                      0
&lt;LI&gt;propagate                                      0
&lt;/UL&gt;
</pre>

<h2 id="dom">Presentation levels and the DOM</h2>

<p>An element's state is first evaluated when it is created. When
the UAPL is changed, all elements in the document have their state
reevaluated. A CSSNowBelowLevel event is then sent to all elements
that changed to the 'below-level' state, a CSSNowAtLevel event is
then sent to all elements that changed to the 'at-level' state, and
a CSSNowAboveLevel event is then sent to all elements that changed
to the 'above-level' state. Changing an element's
'presentation-level' property, e.g. through the DOM or using a
dynamic pseudo-class, does not cause the element's state to be
immediately reevaluated.</p>

<p>These events have the following characteristics:</p>

<ul>
<li>Bubbles: Yes</li>

<li>Cancelable: No</li>

<li>Context Info: detail (the UAPL)</li>
</ul>

<p>SMIL can be used with this event to declaratively key animations
from user requests, based on the 'presentation-index' property.</p>

<p>The events are defined as:</p>

<pre>
   interface CSSNowBelowLevel : UIEvent { }
   interface CSSNowAtLevel : UIEvent { }
   interface CSSNowAboveLevel : UIEvent { }
</pre>

<p>These three fragments together will cause a document to have
three user-triggered list items, which will scroll in one at a time
each time the user hits the space bar (or whatever mechanism the UA
uses), with the current item colored white and the past items
colored gray.</p>

<p>Markup:</p>

<pre>
    &lt;ol&gt;
     &lt;li&gt; The Separation of Style and Structure &lt;/li&gt;
     &lt;li&gt; Declarative User Interaction &lt;/li&gt;
     &lt;li&gt; Potential for Animation &lt;/li&gt;
    &lt;/ol&gt;
</pre>

<p>Stylesheet:</p>

<pre>
     ol { overflow: hidden; }
     li { presentation-level: increment; margin-left: 100%; }
     li:at-level { color: white; }
     li:above-level { color: silver; }
</pre>

<p>Script:</p>

<pre>
    // When the element is shown, scroll it in from the right
    // by animating the margin-left property from 100% to 0%
    document.documentElement.addEventListener('CSSNowAtLevel', handler, false);

    function handler(event) {
      // animateFloat is a (fictional) library routine which takes
      // five arguments:
      //  a CSSValue to animate
      //  the start value
      //  the end value
      //  the time over which to animate the property, in milliseconds
      //  the units to animate it with
      // it returns straight away and performs the animation in the
      // background.
      animateFloat(document.getOverrideStyle(event.target,
                                  null).getPropertyCSSValue('margin-left'),
                   100, 0, 1000, CSS_PERCENTAGE);
    }
</pre>
</body>
</html>
